/**
 * Die Klasse SimpleGameSprite ist die Implementierung eines einfachen
 * Sprites, wie sie ungefähr in der Spieleprogrammierung aussieht. Für
 * gewöhnlich werden in Sprites auch ihre Visualisierung implementiert.
 * Um die Kollision mit einem Sprite o.ä. zu implementieren, wird hier
 * eine Geometrie über das Sprite gelegt. In dieser Klasse wird ein
 * Rechteck verwendet. Schneiden oder berühren sich die Geometrien
 * von 2 oder mehreren Sprites, so handelt es sich um eine Kollision
 * der Sprites. So kann man z.B. steuern, ob das Sprite Hero von dem
 * Sprite Enemy getroffen wurde.
 *
 * @author  Benjamin Friedrich, Ken Dahm
 * @version 1.0  18.01.2009
 */
#ifndef _SIMPLE_GAME_SPRITE_HPP_
#define _SIMPLE_GAME_SPRITE_HPP_

#include <string>

class SimpleGameSprite
{
friend class GameSpriteTest;

private:
	int  sourceX;       // Startkoordinate X
	int  sourceY;		// Startkoordinate Y
	int  destinationX;  // Endkoordinate X (berechnet aus sourceX + width)
	int  destinationY;  // Endkoordinate Y (berechnet aus sourceY + height)
	int  height;        // Höhe der Spielfigur
	int  width;         // Breite der Spielfigur
	int  stepWidth;     // Schrittweite der Spielfigur
	bool isAlive;       // Ist Splielfigur lebendig?

	/**
	 * updateDimension() wird von den moveXXX()-Methoden aufgerufen,
	 * um die Dimension des Sprites ausgehend von sourceX und sourceY
	 * neu zu berechnen.
	 */
	void updateDimension();

public:
	SimpleGameSprite(int x, int y, int width, int height, int stepWidth, bool isAlive = true);
	~SimpleGameSprite(){};

	/**
	 * Bewegt Sprite nach links. Dies geht natürlich nur, wenn das Sprite
	 * "lebendig" ist.
	 *
	 * @throw GameException Wenn versucht wird, das Sprite zu bewegen, obwohl
	 *        diese nicht lebendig ist
	 */
	void moveLeft();

	/**
	 * Bewegt Sprite nach rechts. Dies geht natürlich nur, wenn das Sprite
	 * "lebendig" ist.
	 *
	 * @throw GameException Wenn versucht wird, das Sprite zu bewegen, obwohl
	 *        diese nicht lebendig ist
	 */
	void moveRight();

	/**
	 * Bewegt Sprite nach oben. Dies geht natürlich nur, wenn das Sprite
	 * "lebendig" ist.
	 *
	 * @throw GameException Wenn versucht wird, das Sprite zu bewegen, obwohl
	 *        diese nicht lebendig ist
	 */
	void moveUp();

	/**
	 * Bewegt Sprite nach unten. Dies geht natürlich nur, wenn das Sprite
	 * "lebendig" ist.
	 *
	 * @throw GameException Wenn versucht wird, das Sprite zu bewegen, obwohl
	 *        diese nicht lebendig ist
	 */
	void moveDown();

	/**
	 * hit() gibt an, ob das Sprite mit dem gegebenen Sprite kollidiert
	 *
	 * @param  anderes Sprite
	 */
	bool hit(const SimpleGameSprite& otherEntity) const;

	/**
	 * Legt fest, ob Figur lebendig ist. Man könnte beispielsweise
	 * setAlive(false) aufrufen, wenn man mit einem anderen Sprite
	 * kollidiert.
	 */
	inline void setAlive(bool alive) { this->isAlive = alive; }

	/**
	 * Gibt an, ob das Sprite lebendig ist
	 *
	 * @return true - Figur ist lebendig, false andernfalls
	 */
	inline bool getAlive() const { return this->isAlive;  }


	/**
	 * Die Klasse GameException dient Benachrichtigung von Ausnahmen
	 * innerhalb des Sprites.
	 */
	class GameException
	{
		private: const char *message;
		public:  inline GameException(const char *message = NULL) { this->message = message; };
				 inline const char *toString() const { return this->message; };
	};
};

#endif /* _SIMPLE_GAME_SPRITE_HPP_ */
